/*******************************************************************************
 * Copyright (c) 2012, 2013 XML-Print Project.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     XML-Print Project - initial API and implementation
 ******************************************************************************/
package info.xmlprint.util;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.apache.log4j.Logger;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourceAttributes;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Shell;

public class FileUtil {

	private static boolean checkFile(File file) {
		String fileName = file.getName();

		if (fileName.matches(".*\\.pdf") || fileName.matches(".*\\.fo")
				|| fileName.matches(".*\\.foo")
				|| fileName.matches("\\d*_font\\.xml"))
			return true;
		else
			return false;
	}

	public static void copyFile(File file1, File file2) {

		try {

			FileInputStream fin = new FileInputStream(file1);
			FileOutputStream fout = new FileOutputStream(file2, true);
			byte[] buffer = new byte[512];

			int count;
			// do {
			// count = fin.read(buffer);
			// if (count != -1)
			// fout.write(buffer,0,count);
			// } while (count != -1);
			while ((count = fin.read(buffer)) != -1) {
				fout.write(buffer, 0, count);
			}
			fout.flush();
			fin.close();
			fout.close();

			// System.out.println("Copyfile from " + file1.getAbsolutePath()
			// + " to " + file2.getAbsolutePath());
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public static boolean createFolder(IProject project, String[] names) {
		for (String n : names) {
			IPath path = new Path(n);
			IFolder folder = project.getFolder(path);
			try {
				folder.create(true, true, null);
//				ResourceAttributes res = new ResourceAttributes();
//				res.setReadOnly(true);
//				res.setHidden(false);
//				folder.setResourceAttributes(res);
			} catch (CoreException e) {
				e.printStackTrace();
				return false;
			}

		}
		return true;
	}

	private static void createFolder(IResource resource) {
		IResource parent = resource.getParent();
		if (parent == null) {
			createFolder(parent);
		}
		if (resource instanceof IFolder) {
			IFolder i = (IFolder) resource;
			try {
				if (!i.exists())
					i.create(true, true, null);
			} catch (CoreException e) {
				e.printStackTrace();
			}
		}
	}

	public static boolean delAllFile(String path) {
		boolean flag = false;
		File file = new File(path);
		if (!file.exists()) {
			return flag;
		}
		if (!file.isDirectory()) {
			return flag;
		}
		String[] tempList = file.list();
		File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (path.endsWith(File.separator)) {
				temp = new File(path + tempList[i]);
			} else {
				temp = new File(path + File.separator + tempList[i]);
			}
			if (temp.isFile()) {
				if (checkFile(temp))
					temp.delete();
			}
			if (temp.isDirectory()) {
				delAllFile(path + "/" + tempList[i]);//
				flag = true;
			}
		}
		return flag;
	}

	public static boolean deleteFile(File file) {

		if (file.isFile() && file.exists()) {
			file.delete();
			// System.out.println("Delete file" + file.getName() + " ok");
			return true;
		} else {
			// System.out.println("Delete file" + file.getName() + " error");
			return false;
		}
	}

	public static String getLastFile(String path) {
		File file = new File(path);
		if (!file.exists()) {
			return null;
		}
		if (!file.isDirectory()) {
			return null;
		}

		Long max = (long) 0;
		String outName = null;
		String[] filelist = file.list();

		for (int i = 0; i < filelist.length; i++) {
			File temp = new File(path + "\\" + filelist[i]);
			Long l = temp.lastModified();

			if (max < l) {
				max = l;
				outName = temp.getAbsolutePath();
			}

		}
		return outName;
	}

	public static Object objClone(Object obj) {

		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		ObjectOutputStream p = null;
		try {
			p = new ObjectOutputStream(outputStream);
			p.writeObject(obj);
			p.flush();

		} catch (IOException e) {
			Logger.getLogger(FileUtil.class.getName()).error("", e);
			e.printStackTrace();
		}

		InputStream in = new ByteArrayInputStream(outputStream.toByteArray());
		ObjectInputStream oi = null;
		Object newObj = null;

		try {
			oi = new ObjectInputStream(in);
			newObj = oi.readObject();
		} catch (IOException e) {
			Logger.getLogger(FileUtil.class.getName()).error("", e);
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			Logger.getLogger(FileUtil.class.getName()).error("", e);
			e.printStackTrace();
		}

		return newObj;
	}

	public static void shellSetCenter(Shell shell) {
		Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); //
		int w = d.width; //
		int h = d.height; //
		int x = shell.getSize().x;
		int y = shell.getSize().y;
		x = x < w - 40 ? x : w - 40;
		y = y < h - 80 ? y : h - 80;

		shell.setSize(x, y);

		shell.setLocation(w / 2 - x / 2, h / 2 - y / 2);
	}

	public static void string2StyleText(Shell shell, String string) {

		shellSetCenter(shell);

		final StyledText styledText = new StyledText(shell, SWT.WRAP
				| SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);

		styledText.setText(string);
		styledText.setLayoutData(new GridData(GridData.FILL_BOTH));

		String xmlStr = styledText.getText();
		int start = 0, end;
		for (int i = 0; i < xmlStr.length(); i++) {
			char ch = xmlStr.charAt(i);
			if (ch == '<')
				start = i;
			if (ch == '>') {
				end = i;
				StyleRange sr = new StyleRange();
				sr.start = start;
				sr.length = end - start + 1;
				sr.foreground = styledText.getDisplay().getSystemColor(
						SWT.COLOR_BLUE);
				styledText.setStyleRange(sr);

			}
		}
		shell.open();

	}

	public static boolean write2zip(String input, String output) {
		ZipOutputStream zos = null;
		File in = new File(input);
		try {
			zos = new ZipOutputStream(new FileOutputStream(output));
			zip(in, in.getParentFile(), zos);
			zos.close();
			return true;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	private static void zip(File directory, File base, ZipOutputStream zos)
			throws IOException {
		File[] files = directory.listFiles();
		byte[] buffer = new byte[8192];
		int read = 0;
		if (files.length == 0) {
			zos.putNextEntry(new ZipEntry(directory.getAbsolutePath()
					.substring(base.getPath().length() + 1) + "/"));
		}
		for (int i = 0, n = files.length; i < n; i++) {
			if (files[i].isDirectory()) {
				zip(files[i], base, zos);
			} else {
				FileInputStream in = new FileInputStream(files[i]);
				ZipEntry entry = new ZipEntry(files[i].getPath().substring(
						base.getPath().length() + 1));
				zos.putNextEntry(entry);
				while (-1 != (read = in.read(buffer))) {
					zos.write(buffer, 0, read);
				}
				in.close();
			}
		}
	}

	@SuppressWarnings("resource")
	public static String zip2Project(String file, IProject project,
			boolean searchName) {
		String out = "";

		try {
			ZipFile zipFile = new ZipFile(file);
			InputStream in = new BufferedInputStream(new FileInputStream(file));
			ZipInputStream zipInput = new ZipInputStream(in);
			ZipEntry ze;
			String path;

			while ((ze = zipInput.getNextEntry()) != null) {
				path = ze.getName();
				if (searchName) {
					// if (path.equalsIgnoreCase(".project")) {
					// SAXReader reader = new SAXReader();
					// Document doc = reader.read(zipFile.getInputStream(ze));
					// Node node = doc.selectSingleNode("//name");
					// if (node != null) {
					// out = node.getText();
					// }
					// break;
					//
					// }
					if (ze.isDirectory()) {
						File f = new File(path);
						File p = f.getParentFile();
						while (p != null) {
							if (p.getParentFile() != null) {
								p = p.getParentFile();
							} else
								break;
						}
						return p.getPath();

					}
					continue;
				}

				// add content into project
				File f1 = new File(path);
				File p1 = f1.getParentFile();
				String _path = f1.getName();
				while (p1 != null && p1.getParentFile() != null) {
					_path = p1.getName() + "/" + _path;
					p1 = p1.getParentFile();
				}
				path = _path;
				if (ze.isDirectory()) {
					FileUtil.createFolder(project, new String[] { path });
				} else {
					IFile f = project.getFile(new Path(path));
					if (f.getName().equalsIgnoreCase(".project")) {
						continue;
					}
					createFolder(f.getParent());
					f.create(zipFile.getInputStream(ze), true, null);
				}
			}
			zipInput.closeEntry();
			zipInput.close();
			in.close();
			zipFile.close();
		} catch (IOException | CoreException e) {
			e.printStackTrace();
		}
		return out;
	}

}
